package com.varian.swagger;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import com.varian.misc.VarianApplicationProperties;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

import java.util.Map;

import static org.springdoc.core.properties.SpringDocConfigProperties.ApiDocs.OpenApiVersion.OPENAPI_3_1;

/**
 * @author ben
 * @since 2024/6/22
 */
@AutoConfiguration
@EnableConfigurationProperties(VarianApplicationProperties.class)
public class SwaggerAutoConfig {

    @Bean
    public SwaggerApplicationStarted swaggerApplicationStarted(VarianApplicationProperties properties) {
        return new SwaggerApplicationStarted(properties);
    }

    @Bean
    public OpenAPI globalOpenApiCustomizer(VarianApplicationProperties properties) {
        OpenAPI openApi = new OpenAPI();
        openApi.openapi(OPENAPI_3_1.getVersion())
                .info(new Info()
                        .title(properties.getApplicationName())
                        .version(properties.getVersion())
                        .description(properties.getDescription())
                );
        addBearerAuthentication(openApi);
        if (CollUtil.isNotEmpty(openApi.getTags())) {
            openApi.getTags().forEach(t -> t.setExtensions(Map.of("x-order", RandomUtil.randomInt(0, 100))));
        }
        return openApi;
    }

    private void addBearerAuthentication(OpenAPI openApi) {
        String securityScheme = "Bearer Authentication";
        openApi.addSecurityItem(new SecurityRequirement().addList(securityScheme))
                .components(new Components()
                        .addSecuritySchemes(securityScheme, new SecurityScheme()
                                .name(securityScheme)
                                .type(SecurityScheme.Type.HTTP)
                                .bearerFormat("JWT")
                                .scheme("bearer")));
    }
}
